package com.tamartech.greendb.ui.dialogs;

import org.springframework.richclient.application.event.LifecycleApplicationEvent;
import org.springframework.richclient.dialog.CloseAction;
import org.springframework.richclient.dialog.ConfirmationDialog;
import org.springframework.richclient.dialog.FormBackedDialogPage;
import org.springframework.richclient.dialog.TitledPageApplicationDialog;
import org.springframework.richclient.form.Form;

import com.tamartech.greendb.ui.message.MessageDisplayHandler;

public abstract class AbstractPropertiesDialog extends TitledPageApplicationDialog
{
    private String messagePrefix;
    
    /** The form that allows for editing the object. */
    protected Form form;


    /** Are we creating a new object or editing an existing one? */
    protected boolean creatingNew = false;


    public AbstractPropertiesDialog (String messagePrefix)
    {
        this.messagePrefix = messagePrefix;
        setCloseAction(CloseAction.DISPOSE);
    }

    public AbstractPropertiesDialog (String messagePrefix, boolean creatingNew)
    {
        this (messagePrefix);
        
        this.creatingNew = creatingNew;
    }

    protected void initialiseForm (Form form)
    {
        this.form = form;
        setDialogPage(new FormBackedDialogPage(form));
    }
    
    protected void onAboutToShow()
    {
        if (creatingNew)
        {
            setTitle(getMessage(messagePrefix + ".new.title"));
        }
        else
        {
            String title = getMessage(messagePrefix + ".edit.title", getObjectKeyFields());

            setTitle(title);
        }
    }
    
    protected abstract Object[] getObjectKeyFields();
    
    protected boolean onFinish()
    {
        boolean status = false;
        
        // commit any buffered edits to the model
        form.getFormModel().commit();
        
        try
        {
            // Update the persistent store with the new/modified object.
            String eventType;
            
            if (creatingNew)
            {
                eventType = LifecycleApplicationEvent.CREATED;
                doSave();
            }
            else
            {
                eventType = LifecycleApplicationEvent.MODIFIED;
                doUpdate();
                
            }
            
            // And notify the rest of the application of the change
            getApplicationContext().publishEvent (new LifecycleApplicationEvent(eventType, 
                                                                                form.getFormModel().getFormObject()));
            
            status = true;
        }
        catch (Exception e)
        {
            String msg = getMessage(messagePrefix + ".save.error", getObjectKeyFields());
            
            MessageDisplayHandler mdh = (MessageDisplayHandler) getApplicationContext().getBean("messageDisplayHandler");
            
            mdh.error(msg, e);
        }
        
        return status;
    }
    
    protected abstract void doSave() throws Exception;
    protected abstract void doUpdate() throws Exception;
    

    protected void onCancel()
    {
        // Warn the user if they are about to discard their changes
        if (form.getFormModel().isDirty())
        {
            String msg = getMessage(messagePrefix + ".dirtyCancelMessage");
            String title = getMessage(messagePrefix + ".dirtyCancelTitle");
            ConfirmationDialog dlg = new ConfirmationDialog(title, msg)
            {
                protected void onConfirm()
                {
                    AbstractPropertiesDialog.super.onCancel();
//                    ProjectPropertiesDialog.super.onCancel();
                }
            };
            dlg.showDialog();
        }
        else
        {
            super.onCancel();
        }
    }

    public void setCreatingNew(boolean creatingNew)
    {
        this.creatingNew = creatingNew;
    }

}